import axios from 'axios'
import store from '@/store'
import JSONBigInt from 'json-bigint'
import { getNewToken } from '@/api/user'
import router from '@/router'
const http = axios.create({
  baseURL: 'http://toutiao-app.itheima.net/',
  timeout: 5000,
  transformResponse: [function(data) {
    // 对 data 进行任意转换处理
    try {
      return JSONBigInt.parse(data)
    } catch (error) {
      return data
    }
  }]
})
// 请求拦截器
http.interceptors.request.use(function(config) {
  const token = store.state.user.tokenInfo.token
  // 如果有token并且请求中没有设置Authorization,则自动加上Authorization
  if (token && !config.headers.Authorization) {
    config.headers.Authorization = 'Bearer' + ' ' + token
  }
  return config
}, function(error) {
  // 对请求错误做些什么
  return Promise.reject(error)
})

// 响应拦截器
http.interceptors.response.use(function(response) {
  // 响应成功则直接返回data数据
  return response.data
}, async function(error) {
  // 响应码为401表示token认证失败,先尝试刷新token
  if (error.response.status === 401) {
    const refresh_token = store.state.user.tokenInfo.refresh_token

    // 一. 如果store中有刷新token,就获取新的token
    if (refresh_token) {
      try {
        // 发送请求获取新token
        const res = await getNewToken(refresh_token)

        // 获取成功 ↓↓↓
        // 1.更新store和本地存储中的tokenInfo
        store.commit('user/changeToken',
          { token: res.data.token,
            refresh_token })
        // 2. 获取之前报错的请求对象,并更新token
        // error.config --> 此次报错的请求信息对象
        error.config.headers.Authorization = 'Bearer' + ' ' + res.data.token
        // 3. 重新发请求
        return http(error.config)
      } catch (error) {
        // 获取失败 ↓↓↓
        // 清除store和本地存储中的token,并携带当前目标地址跳转登录页
        noRefreshToken()
      }
    } else {
      // 二. 如果没有刷新token,则清除store和本地存储中的token,并携带当前目标地址跳转登录页
      noRefreshToken()
    }
  }
  return Promise.reject(error)
})

// 清除store和本地存储中的token,并携带当前目标地址跳转登录页
function noRefreshToken() {
  store.commit('user/removeToken')
  router.push({
    path: '/login',
    query: {
      prevPath: router.currentRoute.fullPath
    }
  })
}

export default http
